<template>
  <div class="interface-group section-container" v-loading="groupLoading">
    <div class="section-title">
      接口权限
    </div>
    <div class="section-actions">
      <div class="actions-left">
        <el-button v-permission="['setting:base:auth:add']" type="primary" @click="handleAddGroup()">新建分组</el-button>
        <SearchCmp v-if="searchCmpArray.length" :searchCmpArray="searchCmpArray" :searchForm="queryData" @onSubmit="handleSearch" />
      </div>
    </div>
    <el-row class="content-wrap">
      <el-col :span="5" class="content-left">
        <div class="content-left-header">接口分组</div>
        <div class="content-left-body">
          <el-scrollbar  style="height: calc(100vh - 288px);">
            <el-tree
              v-loading="groupLoading"
              :data="groupTree[0].children"
              :props="groupTreeProps"
              node-key="id"
              :expand-on-click-node="false"
              @node-click="handleChangeGroup"
              :indent="0"
              class="tree-content"
            >
              <template #default="{ node, data }">
                <div class="custom-tree-node">
                  <div class="tree-node-label" :style="{ paddingLeft: (node.level - 1) * 10 + 'px' }" :title="node.label">
                    <i class="iconfont">&#xe6a7;</i>
                    {{ node.label }}
                  </div>
                  <div class="tree-options">
                    <el-dropdown>
                      <i class="iconfont">&#xe78d;</i>
                      <template #dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item><el-button v-permission="['setting:base:auth:add']" type="primary" link @click="handleAddGroup(data, node)">新增</el-button></el-dropdown-item>
                          <el-dropdown-item><el-button v-permission="['setting:base:auth:edit']" type="primary" link @click="handleEditGroup(data)">编辑</el-button></el-dropdown-item>
                          <el-dropdown-item v-if="node.isLeaf"><el-button v-permission="['setting:base:auth:delete']" type="primary" link @click="handleDeleteGroup(data)">删除</el-button></el-dropdown-item>
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                  </div>
                </div>
              </template>
            </el-tree>
          </el-scrollbar>
        </div>
      </el-col>
      <el-col :span="19" class="content-right">
        <div class="content-right-header">
          <div class="header-left">
            <span class="group-name">{{ curGroup ? curGroup.name : '请点击要查看的分组' }}</span>
            <span class="total">{{ `（数量：${interfaceList?.length || 0}）` }}</span>
          </div>
          <div class="header-right">
            <el-button v-permission="['setting:base:auth:add']" type="primary" size="small" @click="handleAddInterface">添加接口</el-button>
            <el-button v-permission="['setting:base:auth:delete']" type="danger" size="small" :disabled="checkedList.length == 0 || !curGroup" @click="handleDeleteInterface()">删除</el-button>
          </div>
        </div>
        <div class="content-right-body">
          <RuifoxTable class="my-table" :loading="tableLoading" :default-index="true" :default-checkbox="true" v-model:tableData="interfaceList" v-model:fieldList="fieldList">
            <template #default-checkbox="{ element }">
              <div class="table-div-check">
                <el-checkbox class="unmover" v-model="element.checked" @change="handleCheckTable(element.id)" size="" />
              </div>
            </template>
            <template #type="{ element }">
              {{ element.type == 1 ? '接口分组' : '权限接口' }}
            </template>
            <template #isOpen="{ element }">
              <el-tag :type="element.isOpen ? 'success' : 'danger'">{{ element.isOpen ? '是' : '否' }}</el-tag>
            </template>
            <template #isUse="{ element }">
              <el-tag :type="element.isUse ? 'success' : 'danger'">{{ element.isUse ? '已启用' : '未启用' }}</el-tag>
            </template>
            <template #pid="{ element }">
              <p>{{ groupMapping[element.pid] }}</p>
            </template>
            <template #state="{ element }">
              <el-tag v-if="element.state === 0" type="success">激活</el-tag>
              <el-tag v-else type="warning">挂起</el-tag>
            </template>
            <template #options="{ element }">
              <div class="table-td-option">
                <el-button v-permission="['setting:base:auth:edit']" type="primary" link @click="handleEditInterface(element)">编辑</el-button>
                <el-button v-permission="['setting:base:auth:delete']" type="primary" link @click="handleDeleteInterface(element)">删除</el-button>
              </div>
            </template>
          </RuifoxTable>
        </div>
      </el-col>
    </el-row>
    <!-- 分组添加、编辑弹窗 -->
    <el-dialog v-model="groupDialog" :title="groupForm.id ? '修改分组' : '添加分组'" width="680px" :draggable="true" @close="resetGroupForm">
        <el-form :model="groupForm" label-width="100px" label-position="left" ref="groupFormRef" :rules="groupFormRules" :inline-message="true">
          <el-form-item label="上级分组:" prop="pid">
            <el-tree-select
              v-model="groupForm.pid"
              placeholder="选择所属上级分组"
              :data="groupTree"
              default-expand-all
              :check-strictly="true"
              :props="groupTreeProps"
            ></el-tree-select>
          </el-form-item>
          <el-form-item label="分组名称" prop="name">
            <el-input v-model="groupForm.name" placeholder="请输入分组名称" />
          </el-form-item>
          <el-form-item label="分组英文名" prop="title">
            <el-input v-model="groupForm.title" placeholder="请输入分组英文名" />
          </el-form-item>
          <el-form-item label="是否启用" prop="isUse">
            <el-switch v-model="groupForm.isUse"></el-switch>
          </el-form-item>
          <el-form-item label="是否公共" prop="isOpen">
            <el-switch v-model="groupForm.isOpen"></el-switch>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button type="primary" @click="handleSubmitGroup">确认</el-button>
            <el-button @click="groupDialog = false">取消</el-button>
          </span>
        </template>
      </el-dialog>
      <!-- 接口添加、编辑弹窗 -->
      <el-dialog v-model="interfaceDialog" :title="interfaceForm.id ? '修改接口' : '添加接口'" width="680px" :draggable="true" @close="resetInterfaceForm">
          <el-form :model="interfaceForm" label-width="100px" label-position="left" ref="interfaceFormRef" :rules="interfaceFormRules" :inline-message="true">
            <el-form-item label="所属分组:" prop="pid">
              <el-tree-select
                v-model="interfaceForm.pid"
                placeholder="选择所属所属分组"
                :data="groupTree"
                default-expand-all
                :check-strictly="true"
                :props="groupTreeProps"
              ></el-tree-select>
            </el-form-item>
            <el-form-item label="接口名称" prop="name">
              <el-input v-model="interfaceForm.name" placeholder="请输入接口名称" />
            </el-form-item>
            <el-form-item label="接口地址" prop="title">
              <el-input v-model="interfaceForm.title" placeholder="请输入接口地址" @blur="formatTitle" />
            </el-form-item>
            <el-form-item label="是否启用" prop="isUse">
              <el-switch v-model="interfaceForm.isUse"></el-switch>
            </el-form-item>
            <el-form-item label="是否公共" prop="isOpen">
              <el-switch v-model="interfaceForm.isOpen"></el-switch>
            </el-form-item>
            <el-form-item label="接口描述" prop="description">
              <el-input v-model="interfaceForm.description" :rows="3" type="textarea" placeholder="请输入接口描述" />
            </el-form-item>
          </el-form>
          <template #footer>
            <span class="dialog-footer">
              <el-button type="primary" @click="handleSubmitInterface">确认</el-button>
              <el-button @click="interfaceDialog = false">取消</el-button>
            </span>
          </template>
        </el-dialog>
      
  </div>
</template>

<script setup>
/* eslint-disable */
import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getAuthorityList, insertAuthority, deleteAuthority, deleteAuthorityList, updateAuthority } from '@/api/auth'
import { createTreeData } from '@ruifox-cms/utils'

/***********************************************************分组相关********************************************/
// 获取分组列表
const groupTreeProps = {
  label: 'name',
  value: 'id',
  children: 'children'
}
const groupTree = ref([
  {
    id: 0,
    children: [],
    name: '系统'
  }
])
const groupMapping = ref({})
const groupLoading = ref(false)
const handleGetGroup = async () => {
  groupLoading.value = true
  const res = await getAuthorityList({type: 1})
  if (res.code === 20000) {
    const treeData = createTreeData(res.data)
    groupTree.value[0].children.push(...treeData)
    groupTree.value = [
      {
        id: 0,
        children: treeData,
        name: '系统'
      }
    ]
  }
  groupLoading.value = false
}
handleGetGroup()

// 切换组别
const curGroup = ref(null)
const handleChangeGroup = data => {
  if(curGroup.value?.id === data.id) return
  curGroup.value = data
  queryData.pid = data.id
  handleGetInterfaceList()
}

// 添加分组
const groupDialog = ref(false)
const groupFormRef = ref(null)
const groupFormRules = reactive({
  name: [{ required: true, message: '请输入分组名称', trigger: 'blur' }],
  pid: [{ required: true, message: '请选择所属上级分组', trigger: 'blur' }],
  title: [{ required: true, message: '请输入分组英文名', trigger: 'blur' }]
})
const defaultGroupForm = reactive({
  "id": null,
  "description": "",
  "isOpen": false,
  "isShow": true,
  "isUse": true,
  "name": "",
  "title": "",
  "pid": 0,
  "type": 1 // 1分组，0权限
})
const groupForm = reactive(Object.assign({}, defaultGroupForm))
const handleAddGroup = (data) => {
  if(data) {
    groupForm.pid = data.id
  } else {
    groupForm.pid = 0
  }
  groupDialog.value = true
}

// 编辑分组
const handleEditGroup = data => {
  Object.assign(groupForm, data)
  groupDialog.value = true
}

// 提交分组
const handleSubmitGroup = () => {
  groupFormRef.value.validate(async valid => {
    if (!valid) return
    let res
    if(groupForm.id){
      res = await updateAuthority(groupForm)
    }else{
      res = await insertAuthority(groupForm)
    }
    if (res.code === 20000) {
      const msg = groupForm.id ? '更新成功' : '创建成功'
      ElMessage.success(msg)
      handleGetGroup()
      groupDialog.value = false
    }
  })
}

// 删除分组
const handleDeleteGroup = async data => {
  ElMessageBox.confirm('是否删除所选分组？', '提示', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      const res = await deleteAuthority({id: data.id})
      if(res.code === 20000) {
        ElMessage.success('删除成功')
        handleGetGroup()
        if(curGroup.value?.id === data.id){
          interfaceList.value = []
          curGroup.value = null
        }
      }
    }).catch(() => {
      ElMessage.info('已取消删除')
    })
}

// 重置表单
const resetGroupForm = () => {
  groupFormRef.value.resetFields()
  Object.assign(groupForm, defaultGroupForm)
}
/***********************************************************接口相关********************************************/
// 接口列表配置
const searchCmpArray = ref([
  { label: '接口名称', key: 'name' },
  { label: '接口地址', key: 'title' }
])
const fieldList = ref([
  {
    title: '名称',
    name: 'name',
    showTextTip: true
  },
  {
    title: '接口地址',
    name: 'title',
    showTextTip: true
  },
  {
    title: '类型',
    name: 'type'
  },
  {
    title: '是否公共',
    name: 'isOpen'
  },
  {
    title: '启用状态',
    name: 'isUse'
  },
  {
    title: '操作',
    width: 180,
    fixed: 'right',
    name: 'options'
  }
])

// 获取接口列表
const tableLoading = ref(false)
const defaultQueryData = reactive({
  name: '',
  title: ''
})
const queryData = reactive(Object.assign({}, defaultQueryData))
const interfaceList = ref([])
const handleGetInterfaceList = async () => {
  tableLoading.value = true
  const res = await getAuthorityList(queryData)
  if (res.code === 20000) {
    interfaceList.value = res.data
  }
  tableLoading.value = false
}

// 搜索
const handleSearch = () => {
  handleGetInterfaceList()
}

// 创建接口
const interfaceDialog = ref(false)
const interfaceFormRef = ref(null)
const interfaceFormRules = reactive({
  name: [{ required: true, message: '请输入接口名称', trigger: 'blur' }],
  title: [{ required: true, message: '请输入接口地址', trigger: 'blur' }],
  pid: [{ required: true, message: '请选择所属分组', trigger: 'blur' }]
})
const defaultInterfaceForm = reactive({
  "id": null,
  "description": "",
  "isOpen": false,
  "isShow": true,
  "isUse": true,
  "name": "",
  "title": "",
  "pid": null,
  "type": 0 // 1分组，0权限
})
const interfaceForm = reactive(Object.assign({}, defaultInterfaceForm))
const handleAddInterface = () => {
  if(curGroup.value){
    interfaceForm.pid = curGroup.value.id
  }
  interfaceDialog.value = true
}

// 编辑
const handleEditInterface = data => {
  Object.assign(interfaceForm, data)
  interfaceDialog.value = true
}

// 接口地址空格处理
const formatTitle = () => {
  interfaceForm.title = interfaceForm.title.replace(/\s/g, '')
}

// 提交接口
const handleSubmitInterface = async () => {
  interfaceFormRef.value.validate(async valid => {
    if (!valid) return
    let res
    if(interfaceForm.id){
      res = await updateAuthority(interfaceForm)
    }else{
      res = await insertAuthority(interfaceForm)
    }
    if (res.code === 20000) {
      const msg = interfaceForm.id? '更新成功' : '创建成功'
      ElMessage.success(msg)
      handleGetInterfaceList()
      interfaceDialog.value = false
    }
  })
}

// 删除接口
const handleDeleteInterface = async data => {
  ElMessageBox.confirm('是否删除所选接口？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      let deleteList = []
      if(data) {
        deleteList = [data.id]
      }else{
        deleteList = checkedList.value
      }
      const res = await deleteAuthorityList({ids: deleteList, isAllChoose: false})
      if(res.code === 20000) {
        ElMessage.success('删除成功')
        checkedList.value = []
        handleGetInterfaceList()
      }
    })
}

// 勾选接口
const checkedList = ref([])
const handleCheckTable = id => {
  if (checkedList.value.includes(id)) {
    checkedList.value = checkedList.value.filter(item => item != id)
  } else {
    checkedList.value.push(id)
  }
}

// 重置表单
const resetInterfaceForm = () => {
  interfaceFormRef.value.resetFields()
  Object.assign(interfaceForm, defaultInterfaceForm)
}
</script>

<style lang="scss" scoped>
.content-top {
  padding: 10px 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #fff;
  .header-left {
    font-size: 18px;
    font-weight: 600;
  }
}
.content-wrap {
  margin-top: 10px;
  border: 1px solid #e4e4e4;
  .content-left {
    overflow-x: hidden;
    .content-left-header {
      height: 50px;
      background-color: $backBase;
      width: 100%;
      box-sizing: border-box;
      border-bottom: 1px solid $borderColor;
      padding-left: 46px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 14px;
    }
    .content-left-body {
      .tree-content{
      ::v-deep .el-tree-node .el-tree-node__content{
        border-bottom: 1px solid $borderColor;
        height: 48px;
      }
      ::v-deep .el-tree-node__label{
        width: calc(100% - 40px);
        .custom-tree-node{
          display: flex;
          justify-content: space-between;
          align-items: center;
          div{
            box-sizing: border-box;
          }
          .tree-node-label,.tree-node-icon{
            width: 90%;
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
          }
          .tree-node-path{
            width: 350px;
            flex-grow: 0;
          }
          .tree-node-type{
            width: 380px;
            flex-grow: 0;
          }
          .tree-options{
            display: flex;
            div.button-box{
              flex-grow: 0;
              position: relative;
              i{
                position: absolute;
                right: 0;
                top: 8px;
                color: $mainColor;
              }
            }
          }
        }
      }
    }
    }
  }
  .content-right {
    border-left: 1px solid #e4e4e4;
    .content-right-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0 13px;
      height: 50px;
      background: #dfe9f5;
      .header-left {
        display: flex;
        align-items: center;
        line-height: 14px;
        font-size: 14px;
        .group-name {
          color: #666;
        }
        .total {
          color: $mainColor;
        }
      }
    }
    .content-right-body {
      width: 100%;
      ::v-deep(.my-table) {
        height: calc(100vh - 288px);
        .el-table__cell {
          height: 50px;
          padding: 4px 0;
        }
        .el-table__header {
          width: 100% !important;
        }
        .el-scrollbar__view {
          width: 100% !important;
        }
        .el-table__body {
          width: 100% !important;
        }
        .my-table-index {
          width: 40px !important;
        }
        .cell {
          height: 100%;
          display: flex;
          align-items: center;
        }
        .dropdown-botton {
          padding: 10px;
          display: flex;
          flex-direction: column;
        }
        .el-badge__content {
          transform: scale(0.7);
          right: -15px;
          top: -8px;
        }
      }
    }
  }
}
</style>
